package com.yuanmei.charts;

import android.content.Context;
import android.graphics.Paint;
import android.text.Html;
import android.text.Spanned;

import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.CandleData;
import com.github.mikephil.charting.data.CandleDataSet;
import com.github.mikephil.charting.data.CandleEntry;
import com.github.mikephil.charting.data.CombinedData;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
//import com.github.mikephil.charting.data.realm.implementation.RealmCandleDataSet;
import com.yuanmei.views.R;
import com.yuanmei.model.KLineChartQuote;
import com.yuanmei.common.Utils;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class KLineChartDataSet implements TaChartData {
    private List<CandleEntry> mCandleList;
    private List<Entry> mSma3CloseList;
    private List<Entry> mSma5CloseList;
    private List<Entry> mSma10CloseList;
    private List<Entry> mSma20CloseList;
    private List<Entry> mSma30CloseList;
    private List<Entry> mSma60CloseList;
    private List<Entry> mSma120CloseList;
    private List<Entry> mSma240CloseList;
    private List<String> mXAxisDates;
    private List<Integer> mIDates;
    private List<Float> mVolumeList;
    private List<Float> mAmountList;
    private List<Float> mTurnOverList;
    private List<Float> mPchgList;
    private List<Float> mCloseList;
    private List<Float> mOpenList;
    private List<Float> mHighList;
    private List<Float> mLowList;
    private CombinedData mKLineCombineData;

    public KLineChartDataSet(final Context fContext, List<KLineChartQuote> hqResults, int showCounts) {
        mXAxisDates = new ArrayList<>();
        mIDates = new ArrayList<>();
        mVolumeList = new ArrayList<>();
        mAmountList = new ArrayList<>();
        mTurnOverList = new ArrayList<>();
        mPchgList = new ArrayList<>();

        mOpenList = new ArrayList<>();
        mHighList = new ArrayList<>();
        mLowList = new ArrayList<>();
        mCloseList = new ArrayList<>();
        mSma3CloseList = new ArrayList<>();
        mSma5CloseList = new ArrayList<>();
        mSma10CloseList = new ArrayList<>();
        mSma20CloseList = new ArrayList<>();
        mSma30CloseList = new ArrayList<>();
        mSma60CloseList = new ArrayList<>();
        mSma120CloseList = new ArrayList<>();
        mSma240CloseList = new ArrayList<>();
        mCandleList = new ArrayList<>();

        int showStart = Math.max(0, hqResults.size() - 1 - showCounts);
        float sma5Summary = 0.0f, sma10Summary = 0.0f, sma20Summary = 0.0f, sma30Summary = 0.0f;
        float sma60Summary = 0.0f, sma120Summary = 0.0f, sma240Summary = 0.0f, sma3Summary = 0.0f;
        for (int i = 0; i < hqResults.size(); i++) {
            KLineChartQuote quote = hqResults.get(i);
            float close = quote.getQuoteClose();
            float open = quote.getQuoteOpen();
            float high = quote.getQuoteHigh();
            float low = quote.getQuoteLow();

            int showIdx = i - showStart;
            if (showIdx >= 0) {
                mHighList.add(high);
                mLowList.add(low);
                mOpenList.add(open);
                mCloseList.add(close);
                mXAxisDates.add(quote.getQuoteDate());
                mIDates.add(quote.getQuoteIDate());
                mVolumeList.add(quote.getQuoteVolume());
                mAmountList.add(quote.getQuoteAmount());
                mTurnOverList.add(quote.getQuoteTurnover());
                mPchgList.add(quote.getQuotePchg());
                mCandleList.add(new CandleEntry(showIdx, high, low, open, close));
            }
            int period = 3;
            sma3Summary = sma3Summary + close - ((i < period) ? 0 : hqResults.get(i - period).getQuoteClose());
            if (showIdx >= 0 && i >= period)
                mSma3CloseList.add(new Entry(showIdx, sma3Summary / period));

            period = 5;
            sma5Summary = sma5Summary + close - ((i < period) ? 0 : hqResults.get(i - period).getQuoteClose());
            if (showIdx >= 0 && i >= period)
                mSma5CloseList.add(new Entry(showIdx, sma5Summary / period));

            period = 10;
            sma10Summary = sma10Summary + close - ((i < period) ? 0 : hqResults.get(i - period).getQuoteClose());
            if (showIdx >= 0 && showIdx >= period)
                mSma10CloseList.add(new Entry(showIdx, sma10Summary / period));

            period = 20;
            sma20Summary = sma20Summary + close - ((i < period) ? 0 : hqResults.get(i - period).getQuoteClose());
            if (showIdx >= 0 && i >= period)
                mSma20CloseList.add(new Entry(showIdx, sma20Summary / period));

            period = 30;
            sma30Summary = sma30Summary + close - ((i < period) ? 0 : hqResults.get(i - period).getQuoteClose());
            if (showIdx >= 0 && i >= period)
                mSma30CloseList.add(new Entry(showIdx, sma30Summary / period));

            period = 60;
            sma60Summary = sma60Summary + close - ((i < period) ? 0 : hqResults.get(i - period).getQuoteClose());
            if (showIdx >= 0 && i >= period)
                mSma60CloseList.add(new Entry(showIdx, sma60Summary / period));

            period = 120;
            sma120Summary = sma120Summary + close - ((i < period) ? 0 : hqResults.get(i - period).getQuoteClose());
            if (showIdx >= 0 && i >= period)
                mSma120CloseList.add(new Entry(showIdx, sma120Summary / period));

            period = 240;
            sma240Summary = sma240Summary + close - ((i < period) ? 0 : hqResults.get(i - period).getQuoteClose());
            if (showIdx >= 0 && i >= period)
                mSma240CloseList.add(new Entry(showIdx, sma240Summary / period));
        }

        CandleDataSet candleSet = new CandleDataSet(mCandleList, "");
        candleSet.setDrawHorizontalHighlightIndicator(false);
        candleSet.setHighlightEnabled(true);
        candleSet.setAxisDependency(YAxis.AxisDependency.LEFT);
        candleSet.setShadowWidth(1f);
        candleSet.setValueTextSize(10f);
        candleSet.setDecreasingColor(fContext.getResources().getColor(R.color.decreasing_color));
        candleSet.setDecreasingPaintStyle(Paint.Style.FILL);
        candleSet.setIncreasingColor(fContext.getResources().getColor(R.color.increasing_color));
        candleSet.setIncreasingPaintStyle(Paint.Style.STROKE);
        //设置开盘价等于收盘价的颜色
        candleSet.setNeutralColor(fContext.getResources().getColor(R.color.decreasing_color));
        candleSet.setShadowColorSameAsCandle(true);
        candleSet.setHighlightLineWidth(1f);
        candleSet.setHighLightColor(fContext.getResources().getColor(R.color.border_color));
        candleSet.setDrawValues(false);
        candleSet.setValueTextColor(fContext.getResources().getColor(R.color.marker_text_color));

        ArrayList<ILineDataSet> smaLineSets = new ArrayList<>();

        if (mSma3CloseList.size() > 0) {
            LineDataSet ma3Set = new LineDataSet(mSma3CloseList, "MA3");
            TaLib.setCommonMaStyle(ma3Set);
            ma3Set.setHighlightEnabled(true);
            ma3Set.setDrawHorizontalHighlightIndicator(true);
            ma3Set.setDrawVerticalHighlightIndicator(true);
            ma3Set.setHighLightColor(fContext.getResources().getColor(R.color.border_color));
            ma3Set.setColor(fContext.getResources().getColor(R.color.ma3));
            smaLineSets.add(ma3Set);
        }

        if (mSma5CloseList.size() > 0) {
            LineDataSet ma5Set = new LineDataSet(mSma5CloseList, "MA5");
            TaLib.setCommonMaStyle(ma5Set);
            ma5Set.setHighlightEnabled(true);
            ma5Set.setDrawHorizontalHighlightIndicator(true);
            ma5Set.setDrawVerticalHighlightIndicator(true);
            ma5Set.setHighLightColor(fContext.getResources().getColor(R.color.border_color));
            ma5Set.setColor(fContext.getResources().getColor(R.color.ma5));
            smaLineSets.add(ma5Set);
        }

        if (mSma10CloseList.size() > 0) {
            LineDataSet ma10Set = new LineDataSet(mSma10CloseList, "MA10");
            TaLib.setCommonMaStyle(ma10Set);
            ma10Set.setColor(fContext.getResources().getColor(R.color.ma10));
            smaLineSets.add(ma10Set);
        }

        if (mSma20CloseList.size() > 0) {
            LineDataSet ma20Set = new LineDataSet(mSma20CloseList, "MA20");
            TaLib.setCommonMaStyle(ma20Set);
            ma20Set.setColor(fContext.getResources().getColor(R.color.ma20));
            smaLineSets.add(ma20Set);
        }

        if (mSma30CloseList.size() > 0) {
            LineDataSet ma30Set = new LineDataSet(mSma30CloseList, "MA30");
            TaLib.setCommonMaStyle(ma30Set);
            ma30Set.setColor(fContext.getResources().getColor(R.color.ma30));
            smaLineSets.add(ma30Set);
        }

        if (mSma60CloseList.size() > 0) {
            LineDataSet ma60Set = new LineDataSet(mSma60CloseList, "MA60");
            ma60Set.setColor(fContext.getResources().getColor(R.color.ma60));
            TaLib.setCommonMaStyle(ma60Set);
            smaLineSets.add(ma60Set);
        }

        if (mSma120CloseList.size() > 0) {
            LineDataSet ma120Set = new LineDataSet(mSma120CloseList, "MA120");
            ma120Set.setColor(fContext.getResources().getColor(R.color.ma120));
            TaLib.setCommonMaStyle(ma120Set);
            smaLineSets.add(ma120Set);
        }

        if (mSma240CloseList.size() > 0) {
            LineDataSet ma240Set = new LineDataSet(mSma240CloseList, "MA240");
            ma240Set.setColor(fContext.getResources().getColor(R.color.ma240));
            TaLib.setCommonMaStyle(ma240Set);
            smaLineSets.add(ma240Set);
        }


        {
            int lastIdx = mHighList.size() - 2;
            float high = mHighList.get(lastIdx);
            float low = mLowList.get(lastIdx);
            float close = mCloseList.get(lastIdx);

            float cdp = (high + low + close * 2) / 4;
            List<Entry> cdbList = new ArrayList<>();
            cdbList.add(new Entry(lastIdx, cdp));
            cdbList.add(new Entry(lastIdx + 1, cdp));
            LineDataSet cdpSet = new LineDataSet(cdbList, "CDP");
            TaLib.setCommonCDPStyle(cdpSet);
            cdpSet.setColor(fContext.getResources().getColor(R.color.cdp_color));
            smaLineSets.add(cdpSet);

            float ah = cdp + (high - low);
            List<Entry> ahList = new ArrayList<>();
            ahList.add(new Entry(lastIdx, ah));
            ahList.add(new Entry(lastIdx + 1, ah));
            LineDataSet ahSet = new LineDataSet(ahList, "CDP");
            TaLib.setCommonCDPStyle(ahSet);
            ahSet.setColor(fContext.getResources().getColor(R.color.cdp_ah_color));
            smaLineSets.add(ahSet);

            float nh = cdp * 2 - low;
            List<Entry> nhList = new ArrayList<>();
            nhList.add(new Entry(lastIdx, nh));
            nhList.add(new Entry(lastIdx + 1, nh));
            LineDataSet nhSet = new LineDataSet(nhList, "nh");
            TaLib.setCommonCDPStyle(nhSet);
            nhSet.setColor(fContext.getResources().getColor(R.color.cdp_nh_color));
            smaLineSets.add(nhSet);

            float nl = cdp * 2 - high;
            List<Entry> nlList = new ArrayList<>();
            nlList.add(new Entry(lastIdx, nl));
            nlList.add(new Entry(lastIdx + 1, nl));
            LineDataSet nlSet = new LineDataSet(nlList, "nl");
            TaLib.setCommonCDPStyle(nlSet);
            nlSet.setColor(fContext.getResources().getColor(R.color.cdp_nl_color));
            smaLineSets.add(nlSet);

            float al = cdp - (high - low);
            List<Entry> alList = new ArrayList<>();
            alList.add(new Entry(lastIdx, al));
            alList.add(new Entry(lastIdx + 1, al));
            LineDataSet alSet = new LineDataSet(alList, "al");
            TaLib.setCommonCDPStyle(alSet);
            alSet.setColor(fContext.getResources().getColor(R.color.cdp_al_color));
            smaLineSets.add(alSet);
        }

        mKLineCombineData = new CombinedData();
        mKLineCombineData.setData(new LineData(smaLineSets));
        mKLineCombineData.setData(new CandleData(candleSet));
    }

    @Override
    public int getXAxisSize() {
        return mXAxisDates.size();
    }

    @Override
    public String getXAxisLabel(int index) {
        String date = "None";
        if (index >= 0 && index < mXAxisDates.size()) {
            date = mXAxisDates.get(index);
        }
        return date;
    }

    public int getIDate(int index) {
        int iDate = 0;
        if (index >= 0 && index < mXAxisDates.size()) {
            String sd = mXAxisDates.get(index);
            sd = sd.split("/")[0];
            try {
                Date date = Utils.sDefaultDateFormat.parse(sd);
                iDate = Utils.getIDateFromDate(date);
            } catch (ParseException e) {
                return 0;
            }
        }
        return iDate;
    }

    @Override
    public Spanned getDescription(int index) {
        return Html.fromHtml("KLine");
    }

    @Override
    public List<String> getXAxisLabelList() {
        return mXAxisDates;
    }

    public float getVolume(int index) {
        if (index >= 0 && index < mVolumeList.size()) {
            return mVolumeList.get(index);
        }
        return 0.0f;
    }

    public float getHigh(int index) {
        if (index >= 0 && index < mHighList.size()) {
            return mHighList.get(index);
        }
        return 0.0f;
    }

    public float getLow(int index) {
        if (index >= 0 && index < mLowList.size()) {
            return mLowList.get(index);
        }
        return 0.0f;
    }

    public float getClose(int index) {
        if (index >= 0 && index < mCloseList.size()) {
            return mCloseList.get(index);
        }
        return 0.0f;
    }

    public float getOpen(int index) {
        if (index >= 0 && index < mOpenList.size()) {
            return mOpenList.get(index);
        }
        return 0.0f;
    }

    public float getAmount(int index) {
        if (index >= 0 && index < mAmountList.size()) {
            return mAmountList.get(index);
        }
        return 0.0f;
    }

    public float getTurnOver(int index) {
        if (index >= 0 && index < mTurnOverList.size()) {
            return mTurnOverList.get(index);
        }
        return 0.0f;
    }

    public float getChangePercent(int index) {
        if (index >= 0 && index < mPchgList.size()) {
            return mPchgList.get(index);
        }
        return 0.0f;
    }

    public CandleEntry getCandleEntry(int index) {
        CandleEntry entry = null;
        if (index >= 0 && index < mCandleList.size()) {
            entry = mCandleList.get(index);
        }
        return entry;
    }

    public String getCloseSma5(int index) {
        String value = "null";
        int lack = mXAxisDates.size() - mSma5CloseList.size();
        index = index - lack;
        if (index >= 0 && index < mSma5CloseList.size()) {
            value = Utils.priceToDecimalString(mSma5CloseList.get(index).getY());
        }
        return value;
    }

    public String getCloseSma3(int index) {
        String value = "null";
        int lack = mXAxisDates.size() - mSma3CloseList.size();
        index = index - lack;
        if (index >= 0 && index < mSma3CloseList.size()) {
            value = Utils.priceToDecimalString(mSma3CloseList.get(index).getY());
        }
        return value;
    }

    public String getCloseSma10(int index) {
        String value = "null";
        int lack = mXAxisDates.size() - mSma10CloseList.size();
        index = index - lack;
        if (index >= 0 && index < mSma10CloseList.size()) {
            value = Utils.priceToDecimalString(mSma10CloseList.get(index).getY());
        }
        return value;
    }

    public String getCloseSma20(int index) {
        String value = "null";
        int lack = mXAxisDates.size() - mSma20CloseList.size();
        index = index - lack;
        if (index >= 0 && index < mSma20CloseList.size()) {
            value = Utils.priceToDecimalString(mSma20CloseList.get(index).getY());
        }
        return value;
    }

    public String getCloseSma30(int index) {
        String value = "null";
        int lack = mXAxisDates.size() - mSma30CloseList.size();
        index = index - lack;
        if (index >= 0 && index < mSma30CloseList.size()) {
            value = Utils.priceToDecimalString(mSma30CloseList.get(index).getY());
        }
        return value;
    }

    public String getCloseSma60(int index) {
        String value = "null";
        int lack = mXAxisDates.size() - mSma60CloseList.size();
        index = index - lack;
        if (index >= 0 && index < mSma60CloseList.size()) {
            value = Utils.priceToDecimalString(mSma60CloseList.get(index).getY());
        }
        return value;
    }

    public String getCloseSma120(int index) {
        String value = "null";
        int lack = mXAxisDates.size() - mSma120CloseList.size();
        index = index - lack;
        if (index >= 0 && index < mSma120CloseList.size()) {
            value = Utils.priceToDecimalString(mSma120CloseList.get(index).getY());
        }
        return value;
    }

    public String getCloseSma240(int index) {
        String value = "null";
        int lack = mXAxisDates.size() - mSma240CloseList.size();
        index = index - lack;
        if (index >= 0 && index < mSma240CloseList.size()) {
            value = Utils.priceToDecimalString(mSma240CloseList.get(index).getY());
        }
        return value;
    }

    public List<Integer> getIDateList() {
        return mIDates;
    }

    @Override
    public CombinedData getTaChartData() {
        return mKLineCombineData;
    }
}
